package com.ruoyi.business.service.impl;

import com.ruoyi.business.domain.BusinessFunctionTree;
import com.ruoyi.business.domain.ExtBusinessFunction;
import com.ruoyi.business.domain.ExtPage;
import com.ruoyi.business.domain.ExtPageBusinessFunctionRela;
import com.ruoyi.business.mapper.ExtPageBusinessFunctionRelaMapper;
import com.ruoyi.business.mapper.ExtPageMapper;
import com.ruoyi.business.service.IExtBusinessFunctionService;
import com.ruoyi.business.service.IExtPageService;
import com.ruoyi.common.core.context.SecurityContextHolder;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 页面定义Service业务层处理
 *
 * @author ruoyi
 * @date 2024-01-28
 */
@Service
public class ExtPageServiceImpl implements IExtPageService
{
    @Autowired
    private ExtPageMapper extPageMapper;
    @Autowired
    private ExtPageBusinessFunctionRelaMapper   extPageBusinessFunctionRelaMapper;
    @Autowired
    private IExtBusinessFunctionService extBusinessFunctionService;
    /**
     * 查询页面定义
     *
     * @param id 页面定义主键
     * @return 页面定义
     */
    @Override
    public ExtPage selectExtPageById(Long id)
    {
        return extPageMapper.selectExtPageById(id);
    }

    /**
     * 查询页面定义列表
     *
     * @param extPage 页面定义
     * @return 页面定义
     */
    @Override
    public List<ExtPage> selectExtPageList(ExtPage extPage)
    {
        return extPageMapper.selectExtPageList(extPage);
    }

    /**
     * 新增页面定义
     *
     * @param extPage 页面定义
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long insertExtPage(ExtPage extPage)
    {
        //校验入口参数
        verifyInsertParameter(extPage);
        int rowNum = extPageMapper.insertExtPage(extPage);
        //插入业务功能页面关系表
        ExtPageBusinessFunctionRela relaVo;
        relaVo = new ExtPageBusinessFunctionRela();
        relaVo.setPageCode(extPage.getPageCode());
        relaVo.setBusinessCode(extPage.getBusinessCode());
        relaVo.setCreateTime(DateUtils.getNowDate());
        relaVo.setCreateBy(extPage.getCreateBy());
        relaVo.setEnterpriseCode(extPage.getEnterpriseCode());
        relaVo.setApplicationCode(extPage.getApplicationCode());
        extPageBusinessFunctionRelaMapper.insertExtPageBusinessFunctionRela(relaVo);
        //返回页面id
        return extPage.getId();
    }

    /**
     * 校验新增参数
     * @param extPage
     */
    private void verifyInsertParameter(ExtPage extPage) {
        //入口参数不能为空
        if (extPage == null)
            throw new ServiceException("新增参数不能为空！");
        //业务编码不能为空
        if (StringUtils.isEmpty(extPage.getBusinessCode()))
            throw new ServiceException("业务编码不能为空！");
        //模块类型不能为空
        if (StringUtils.isEmpty(extPage.getModule()))
            throw new ServiceException("模块类型不能为空！");
        //页面编码不能为空
        if (StringUtils.isEmpty(extPage.getPageCode()))
            throw new ServiceException("页面编码不能为空！");
        //页面名称不能为空
        if (StringUtils.isEmpty(extPage.getPageName()))
            throw new ServiceException("页面名称不能为空！");
        //页面类型编码不能为空
        if (StringUtils.isEmpty(extPage.getPageTypeCode()))
            throw new ServiceException("页面类型不能为空！");
        //同一个模块下页面编码不能重复
        Map<String, Object> searchMap = new HashMap<>();
        searchMap.put("pageCode", extPage.getPageCode());
        searchMap.put("module", extPage.getModule());
        if (extPageMapper.selectCount(searchMap) > 0)
            throw new ServiceException("页面编码已经存在!");
        //同一个模块下页面名称不能重复
        searchMap.clear();
        searchMap.put("pageName", extPage.getPageName());
        searchMap.put("module", extPage.getModule());
        if (extPageMapper.selectCount(searchMap) > 0)
            throw new ServiceException("页面名称已经存在!");

    }
    /**
     * 修改页面定义
     *
     * @param extPage 页面定义
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateExtPage(ExtPage extPage)
    {
        //校验更新参数
        verifyUpdateParameter(extPage);
        ExtPage oldExtPage = extPageMapper.selectExtPageById(extPage.getId());

        int rowNum = extPageMapper.updateExtPage(extPage);
        if(rowNum>0){
            if(!oldExtPage.getPageCode().equals(extPage.getPageCode())){
                //页面编码发生变化，需要修改关系表的页面编码
                Map<String,Object> updateMap = new HashMap<>();
                updateMap.put("pageCode",extPage.getPageCode());
                updateMap.put("oldPageCode",oldExtPage.getPageCode());
                updateMap.put("businessCode",extPage.getBusinessCode());
                extPageBusinessFunctionRelaMapper.updatePageCode(updateMap);
            }
        }
        return rowNum;
    }

    /**
     *  校验更新参数
     * @param extPage
     */
    private void verifyUpdateParameter(ExtPage extPage) {
        //入口参数不能为空
        if (extPage == null)
            throw new ServiceException("更新参数不能为空！");
        //更新id不能为空
        if (extPage.getId()==null||extPage.getId()==0L)
            throw new ServiceException("更新id不能为空!");
        //业务编码不能为空
        if (StringUtils.isEmpty(extPage.getBusinessCode()))
            throw new ServiceException("业务编码不能为空！");
        //模块类型不能为空
        if (StringUtils.isEmpty(extPage.getModule()))
            throw new ServiceException("模块类型不能为空！");
        //页面编码不能为空
        if (StringUtils.isEmpty(extPage.getPageCode()))
            throw new ServiceException("页面编码不能为空！");
        //页面名称不能为空
        if (StringUtils.isEmpty(extPage.getPageName()))
            throw new ServiceException("页面名称不能为空！");
        //页面类型编码不能为空
        if (StringUtils.isEmpty(extPage.getPageTypeCode()))
            throw new ServiceException("页面类型不能为空！");
        //同一个模块下页面编码不能重复
        Map<String, Object> searchMap = new HashMap<>();
        searchMap.put("pageCode", extPage.getPageCode());
        searchMap.put("module", extPage.getModule());
        searchMap.put("notId", extPage.getId());
        if (extPageMapper.selectCount(searchMap) > 0)
            throw new ServiceException("页面编码已经存在!");
        //同一个模块下页面名称不能重复
        searchMap.clear();
        searchMap.put("pageName", extPage.getPageName());
        searchMap.put("module", extPage.getModule());
        searchMap.put("notId", extPage.getId());
        if (extPageMapper.selectCount(searchMap) > 0)
            throw new ServiceException("页面名称已经存在!");
    }

    /**
     * 批量删除页面定义
     *
     * @param ids 需要删除的页面定义主键
     * @param businessCode
     * @return 结果
     */
    @Override
    public int deleteExtPageByIds(Long[] ids, String businessCode)
    {
        int sum =0;
        for(Long id:ids){
            sum += deleteExtPageById(id,businessCode);
        }
        return sum;
    }

    /**
     * 删除页面定义信息
     *
     * @param id 页面定义主键
     * @return 结果
     */
    @Override
    public int deleteExtPageById(Long id,String businessCode)
    {
        //查询页面信息
        ExtPage extPage = extPageMapper.selectExtPageById(id);
        extPage.setBusinessCode(businessCode);
        int rowNum =  extPageMapper.deleteExtPageById(id);
        //删除页面功能关系表
        extPageBusinessFunctionRelaMapper.deleteByBusinessCodePageCode(extPage);
        return rowNum;
    }

    /**
     * 更新页面设计
     *
     * @param extPage
     * @return
     */
    @Override
    public int updateDesign(ExtPage extPage) {
        //校验更新页面设计入口参数
        verifyUpdateDesign(extPage);
        //更新页面内容
        return extPageMapper.updateExtPage(extPage);

    }

    /**
     * 查询所有页面树列表
     *
     * @param extPage
     * @return
     */
    @Override
    public List<BusinessFunctionTree> treeList(ExtPage extPage) {
        ExtBusinessFunction extBusinessFunction = new ExtBusinessFunction();
        List<BusinessFunctionTree> tree = extBusinessFunctionService.selectCommonBusinessFunctionTree(extBusinessFunction);

        fillAllBusinessNode(tree);
        //查询接口列表
        List<ExtPage> extPageList = extPageMapper.selectListAssignBusinessFunction(extPage);
        fillTreeWithPageList(tree,extPageList);
        return tree;
    }

    /**
     * 转换extPage列表为业务功能树节点
     *
     * @param list
     * @return
     */
    @Override
    public List<BusinessFunctionTree> toBusinessFunctionTree(List<ExtPage> list) {
        List<BusinessFunctionTree> listTree = new ArrayList<>();
        for(ExtPage page:list) {
            BusinessFunctionTree businessFunctionTree = new BusinessFunctionTree();
            listTree.add(businessFunctionTree);
            businessFunctionTree.setValue(page.getPageCode());
            businessFunctionTree.setLabel(page.getPageName());
            businessFunctionTree.setNodeData(page.getPageScheme());
            businessFunctionTree.setNodeType(BusinessFunctionTree.NODE_TYPE_PAGE);
            businessFunctionTree.setParentCode(page.getBusinessCode());
            businessFunctionTree.setHasChildren(true);
        }
        return listTree;
    }

    @Override
    public ExtPage getPageByCode(String pageCode, String enterpriseCode, String applicationCode) {

        ExtPage searchExtPage = new ExtPage();
        searchExtPage.setPageCode(pageCode);
        SecurityContextHolder.setEnterpriseCode(enterpriseCode);
        SecurityContextHolder.setApplicationCode(applicationCode);
        List<ExtPage> vos = extPageMapper.selectExtPageList(searchExtPage);
        if(CollectionUtils.isEmpty(vos))
            throw new ServiceException("页面编码不存在！");
        return vos.get(0);
    }

    @Override
    public ExtPage getPageById(Long pageId, String enterpriseCode, String applicationCode) {
        ExtPage searchExtPage = new ExtPage();
        searchExtPage.setId(pageId);
        SecurityContextHolder.setEnterpriseCode(enterpriseCode);
        SecurityContextHolder.setApplicationCode(applicationCode);
        List<ExtPage> vos = extPageMapper.selectExtPageList(searchExtPage);
        if(CollectionUtils.isEmpty(vos))
            throw new ServiceException("页面id不存在！");
        return vos.get(0);
    }

    private void fillAllBusinessNode(List<BusinessFunctionTree> tree) {
        //设置节点类型
        for(BusinessFunctionTree node:tree){
            node.setNodeType(BusinessFunctionTree.NODE_TYPE_BUSINESS);
            if(!CollectionUtils.isEmpty(node.getChildren())){
                fillAllBusinessNode(node.getChildren());
            }
        }
    }

    /**
     * 把页面挂到功能树下
     * @param tree
     * @param extPageList
     */
    private void fillTreeWithPageList(List<BusinessFunctionTree> tree, List<ExtPage> extPageList) {
        for(BusinessFunctionTree node:tree){
            recursionFillTree(node,extPageList);
        }
    }


    /**
     * 递归填充树节点
     * @param node 树节点
     * @param extPageList
     */
    private void recursionFillTree(BusinessFunctionTree node, List<ExtPage> extPageList) {
        //如果有下级节点，则递归下级，直到没有下级
        if(node.getChildren()!=null && node.getChildren().size()>0){
            for(BusinessFunctionTree child:node.getChildren()){
                recursionFillTree(child,extPageList);
            }
        }else{
            //查询属于当前业务编码的页面列表
            List<ExtPage> childList = extPageList.stream().filter(extPage -> extPage.getBusinessCode().equals(node.getValue())).collect(Collectors.toList());
            node.setChildren(toBusinessFunctionTreeList(node.getValue(),childList));
        }
    }

    /**
     * 转换页面列表为业务功能树列表
     *
     * @param parentCode
     * @param childList
     * @return
     */
    private List<BusinessFunctionTree> toBusinessFunctionTreeList(String parentCode, List<ExtPage> childList) {
        List<BusinessFunctionTree> retList = new ArrayList<>();
//        for(ExtPage child:childList){
            childList.forEach(extPage -> {
                BusinessFunctionTree businessFunctionTree = new BusinessFunctionTree();
                businessFunctionTree.setValue(extPage.getPageCode());
                businessFunctionTree.setLabel(extPage.getPageName());
                businessFunctionTree.setParentCode(parentCode);
                businessFunctionTree.setNodeType(BusinessFunctionTree.NODE_TYPE_PAGE);
                businessFunctionTree.setNodeData(extPage.getPageScheme());
                retList.add(businessFunctionTree);
            });
//        }
        return retList;
    }
    /**
     * 校验更新页面设计入口参数
     *
     * @param extPage 页面设计
     * @return
     */
    private void verifyUpdateDesign(ExtPage extPage) {
        //入口参数不能为空
        if(extPage==null)
            throw new ServiceException("入口参数不能为空");
        //id不能为空
        if(extPage.getId()==null||extPage.getId()==0L)
            throw new ServiceException("id不能为空");
        //页面内容不能为空
        if(StringUtils.isEmpty(extPage.getPageScheme()))
            throw new ServiceException("页面内容不能为空");
    }
}
